# coding=utf-8
# import sesson1.udp as udp
import json
import math
import random
import csv
import ctypes
from tkinter.constants import PROJECTING
import matplotlib.colors as mcolors
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# from .import base_fun as fun
# from .import networkx_graph as xgh
# import sesson1.globalvar as Globalvar
import base_fun as fun
import networkx_graph31 as xgh
colors = list(dict(mcolors.BASE_COLORS, **mcolors.CSS4_COLORS).keys())


def filter_people():
    with open("./data/data2cpp.json", 'r') as load_f:
        load_dict = json.load(load_f)

    rescue_peoples = [[], [], []]

    for idex in range(len(load_dict["car_points"])):
        for point in load_dict["car_points"][idex]["pass_points"]:
            rescue_peoples[idex].append(
                [point["longitude"], point["latitude"]])
    # print(rescue_peoples)
    datasets = (np.array(rescue_peoples[0]), np.array(
        rescue_peoples[1]), np.array(rescue_peoples[2]))

    for idex in range(3):
        # plt.figure() #另起一张新的画布
        plt.plot(datasets[idex][:, 1], datasets[idex][:, 0],
                 color=colors[idex], label='t2', marker='o')

    plt.show()
    return datasets


def GetDistance(p1, p2):
    lat1 = p1[1]
    long1 = p1[0]
    lat2 = p2[1]
    long2 = p2[0]
    return GetDistance2(lat1, long1, lat2, long2)


def GetDistance2(lat1, long1, lat2, long2):
    # print(lat1, long1, lat2, long2)
    val = math.sin(lat1 * 0.01745329) * math.sin(lat2 * 0.01745329) + math.cos(lat1 *
                                                                               0.01745329) * math.cos(lat2 * 0.01745329) * math.cos((long1 - long2) * 0.01745329)
    return 6378137 * math.acos(val)


def cal_cost(lstt, point):
    minval = []
    minlist = []
    for j in range(20):
        sum = 0
        ls = list(lstt)
        for i in range(len(ls)-1):
            sum += GetDistance(point[ls[i]], point[ls[i+1]])
        # print(sum)
        minval.append(sum)
        minlist.append(ls)
        random.shuffle(lstt)
    ret_ls = minlist[minval.index(min(minval))]
    return min(minval), minval.index(min(minval)), ret_ls


def cal_cost(lstt, point):
    minval = []
    minlist = []
    for j in range(20):
        sum = 0
        ls = list(lstt)
        for i in range(len(ls)-1):
            sum += GetDistance(point[ls[i]], point[ls[i+1]])
        # print(sum)
        minval.append(sum)
        minlist.append(ls)
        random.shuffle(lstt)
    ret_ls = minlist[minval.index(min(minval))]
    return min(minval), minval.index(min(minval)), ret_ls


def calpath(txdatx):

    dlen = len(txdatx)
    minindex = txdatx[0]  # min(txdatx)
    new_list = []
    new_list.append(minindex)  # listname[index]
    # print(new_list, txdatx.index(min(txdatx)))
    del txdatx[0]  # txdatx.index(min(txdatx))
    # print(min(txdatx))
    dis = []
    while(len(txdatx) > 0):
        for idd in range(len(txdatx)):
            dis.append(GetDistance2(
                txdatx[idd][0], txdatx[idd][1], minindex[0], minindex[1]))
        minindex = txdatx[dis.index(min(dis))]
        new_list.append(minindex)
        del txdatx[dis.index(min(dis))]
        dis = []
    data2 = pd.DataFrame(new_list, columns=[
                         'longitude', 'latitude', 'label', 'people_id'])
    return data2


def msort(txdatx):
    newlis = list(txdatx)
    ret = calpath(newlis)
    # print(txdatx)
    return ret


def sesson2_2_main(round_id):
    rp, center = fun.out_data(round_id)  # 计算待救人ID

    d1 = rp[0]  # .sample(n=75)
    d2 = rp[1]  # .sample(n=75)
    d3 = rp[2]  # .sample(n=75)

    sd1 = np.array(d1).tolist()  # np.ndarray()
    sd2 = np.array(d2).tolist()  # np.ndarray()
    sd3 = np.array(d3).tolist()  # np.ndarray()
    sd0 = (msort(sd1), msort(sd2), msort(sd3))
    # fun.toJons(addd, "./data/data2cpp.json")
    # fun.toJonsPeolpes(sd0)
    # gen_people_path()
    # points = fun.view_maps(True)
    # plt.show()
    # filter_people()  # 过滤一些
    # read_txt()
    xgh._main_fun(sd0, round_id)

    return True


def read_txt():
    fname = 'outpath.csv'
    points = fun.view_maps(False)
    paths = [[], [], []]
    point_ids = [[], [], []]
    with open(fname, 'r+', encoding='utf-8') as txtf:
        lines = txtf.readlines()
        # print(len(lines))

    for index, line in enumerate(lines):
        point_ids[index] = (list(int(i) for i in line.split(",")))

    for index in range(3):
        #         # print(line)

        for val in point_ids[1]:
            paths[index].append(points[val])
    data1 = pd.DataFrame(paths[0], columns=['x', 'y'])
    data2 = pd.DataFrame(paths[1], columns=['x', 'y'])
    data3 = pd.DataFrame(paths[2], columns=['x', 'y'])
    fun.toJons((data1, data2, data3), './data/send_data.json')


def view_my_path(paths):
    for idex, path in enumerate(paths):
        data = np.array(path)
        plt.plot(data[:, 1], data[:, 0],
                 color=colors[idex+3], label='t2'+str(idex), marker='.')
    plt.show()


def view_randm_path():
    # gen_people_path()
    points = fun.view_maps(True)
    path = []
    paths = []
    point_id = []
    point_ids = []
    fname = 'C:\\Users\\tang\\Desktop\\RHZT\R1\\jsontest3\\outrandmpath.csv'
    with open(fname, 'r+', encoding='utf-8') as txtf:
        lines = txtf.readlines()
    for index, line in enumerate(lines):
        point_ids.append(list(int(i) for i in line.split(",")))
    for index, val in enumerate(point_ids):
        for val in val:
            path.append(points[val])
        paths.append(path)
        path = []
    # print(paths)

    view_my_path(paths)

    filter_people()


def gen_people_path():
    # gen_path = "C:\\Users\\tang\\Desktop\\cmd\\cpp_app\\data\\gen_people_25.csv"
    gen_path = "C:\\Users\\tang\\Desktop\\cmd\\data\\gen_people_25.csv"
    # test_dll = ctypes.cdll.LoadLibrary(
    #     'C:\\Users\\tang\\Desktop\\cmd\\cpp_app\\x64\\Release\\jsontest.dll')
    # ret = test_dll.gen_people_25(1000)
    # print(ret)
    gen_paths(
        reapath=gen_path,
        out_path='C:\\Users\\tang\\Desktop\\RHZT\\Test_Exam\\session\\session_2\\subject_2\\team_path_2.json'
    )


def gen_different_path():
    gen_path = "C:\\Users\\tang\\Desktop\\cmd\\cpp_app\\data\\gen_people_25.csv"
    test_dll = ctypes.cdll.LoadLibrary(
        'C:\\Users\\tang\\Desktop\\cmd\\cpp_app\\x64\\Release\\jsontest.dll')
    ret = test_dll.gen_differnent_paths(10, 15000, 10)
    print(ret)
    gen_paths(
        reapath=gen_path,
        out_path='C:\\Users\\tang\\Desktop\\RHZT\\Test_Exam\\session\\session_2\\subject_2\\team_path_02.json'
    )


def gen_paths(reapath, out_path):
    points = fun.view_maps(False)
    paths = [[], [], []]
    point_ids = [[], [], []]
    with open(reapath, 'r+', encoding='utf-8') as txtf:
        lines = txtf.readlines()
        # print(len(lines))

    for index, line in enumerate(lines):
        point_ids[index] = (list(int(i) for i in line.split(",")))

    for index in range(3):
        for val in point_ids[index]:
            paths[index].append(points[val])

    data1 = pd.DataFrame(paths[0], columns=['y', 'x'])
    data2 = pd.DataFrame(paths[1], columns=['y', 'x'])
    data3 = pd.DataFrame(paths[2], columns=['y', 'x'])
    # print(out_path)
    fun.toJons((data1, data2, data3), out_path)


# Ui界面调用进行预处理


# def preprocess(Objdll, s1):
#     # 读图
#     local_ip = udp.socket.gethostbyname(udp.socket.gethostname())
#     s1.bind((local_ip, 10014))
#     # print("local_ip:",local_ip)
#     print('Bind UDP on 10014...')
#     # 创建线程接收数据
#     recv_thread = udp.threading.Thread(target=udp.recvmsg, args=(s1,))
#     recv_thread.start()
#     return True
# Ui界面调用运行科目1


# def session2_2_main(Objdll, s):
#     while True:

#         if Globalvar.get_recv_msg_content():
#             Globalvar.set_recv_msg_content(False)

#             # 根据报文读取对应科目、情景下的client_path_.json文件
#             temp_content = Globalvar.get_msg_content_value()
#             examRound = Globalvar.get_exam_round()
#             sesson2_2_main(examRound)  # 计算结果
#             # client_path_content = read_client_path(temp_content[0], temp_content[1], exam_round=examRound)
#             # if dlltest.transfer_client_path(Objdll, client_path_content, temp_content[0], temp_content[1]):
#             #     # 数据传入完成，算法计算完毕，向平台发送完成指令
#             udp.sentmsg(temp_content[0], temp_content[1], s, Globalvar.get_send_id_addr(
#             ), exam_round=examRound, info=3)
#             break


if __name__ == '__main__':
    sesson2_2_main()
